<template>
    <div class="do-task-page">
      <div class="fullscreen-bg" aria-hidden="true"></div>
  
      <header class="page-header">
        <div class="back-row">
          <a-button @click="goBack">返回</a-button>
        </div>
        
        <span class="subtitle" v-if="task">
          完成任务：{{ task.title }}
        </span>
        <span class="subtitle" v-else>未找到任务信息</span>
      </header>
  
      <div v-if="task" class="content-wrap">
        <aside class="steps-panel grid-left">
          <div class="steps-header">任务步骤</div>
          <a-steps direction="vertical" :current="currentStep" class="steps-list" style="height: 90%;">
            <a-step v-for="(s, idx) in stepItems" :key="idx" :title="s.title" :description="s.desc" />
          </a-steps>
          <div class="steps-actions">
            <a-button size="small" @click="prevStep" :disabled="currentStep===0">上一步</a-button>
            <a-button size="small" type="primary" @click="nextStep" :disabled="currentStep===stepItems.length-1">下一步</a-button>
          </div>
        </aside>
  
        <section class="task-intro grid-intro grid-card" id="task-intro">
          <h3>任务简介</h3>
          <p class="desc">{{ task.description }}</p>
          <div class="meta">
            <div class="meta-item"><span>类型：</span>{{ typeLabel(task.type) }}</div>
            <div class="meta-item"><span>难度：</span>{{ difficultyLabel(task.difficulty) }}</div>
            <div class="meta-item"><span>截止：</span>{{ formatDate(task.deadline) }}</div>
            <div class="meta-item"><span>预计用时：</span>{{ task.estimatedTime }} 分钟</div>
          </div>
        </section>
  
        <section class="task-editor grid-editor grid-card" id="editor-section">
          <div class="editor-header">
            <h3>作答区域</h3>
            <div class="actions">
              <a-button @click="openCodeDialog">插入代码</a-button>
              <a-button @click="saveDraft" :loading="saving">保存草稿</a-button>
              <a-button type="primary" @click="submitAnswer" :loading="submitting">提交答案</a-button>
            </div>
          </div>
  
          <div class="editor-card">
            <QuillEditor
              ref="quillRef"
              v-model:content="answer"
              contentType="html"
              theme="snow"
              :toolbar="toolbar"
              class="rich-editor"
            />
          </div>
        </section>
      </div>
  
      <a-empty v-else description="暂无任务数据，请从任务中心进入" />
  
      <!-- 代码插入弹窗 -->
      <a-modal v-model:open="codeDialogVisible" title="插入代码" :width="1100" @afterClose="disposeMonaco">
        <div class="code-editor-wrap">
          <div class="code-toolbar">
            <span class="label">语言：</span>
            <a-select v-model:value="codeLang" size="small" class="lang-select" @change="onChangeLang" style="width: 100px;">
              <a-select-option v-for="opt in langOptions" :key="opt.value" :value="opt.value">{{ opt.label }}</a-select-option>
            </a-select>
          </div>
          <div class="monaco-wrap">
            <div ref="monacoEl" class="monaco-container"></div>
          </div>
  
  
          <div class="code-preview" id="run-result">
            <div class="run-status" :class="runStatus">
              {{ runStatus === 'success' ? '运行成功' : runStatus === 'error' ? '运行失败' : '运行结果' }}
            </div>
            <iframe class="preview-frame" :srcdoc="previewHtml"></iframe>
          </div>
        </div>
  
        <template #footer>
          <a-button :loading="runLoading" type="primary" @click="runCodePreview">运行</a-button>
          <a-button @click="codeDialogVisible = false">取消</a-button>
          <a-button type="primary" @click="insertCodeIntoEditor">插入到文档</a-button>
        </template>
      </a-modal>
    </div>
  </template>
  
  <script setup>
  import { ref, onMounted, nextTick, onUnmounted } from 'vue'
  import { useRoute, useRouter } from 'vue-router'
  import { message, Modal } from 'ant-design-vue'
  import { QuillEditor } from '@vueup/vue-quill'
  import '@vueup/vue-quill/dist/vue-quill.snow.css'
  import hljs from 'highlight.js/lib/common'
  import 'highlight.js/styles/github.css'
  import * as monaco from 'monaco-editor'
  import { runAdvanced } from '../api/run'
  
  const route = useRoute()
  const router = useRouter()
  
  // 请求通过 Vite 代理到后端，避免浏览器直连跨域
  
  const STORAGE_CURRENT = 'pp_current_task'
  const ANSWER_KEY_PREFIX = 'pp_task_answer_'
  
  const task = ref(null)
  const answer = ref('')
  const saving = ref(false)
  const submitting = ref(false)
  const quillRef = ref(null)
  const currentStep = ref(0)
  const stepItems = [
    { title: '阅读任务', desc: '先通读任务简介与要求' },
    { title: '编写代码', desc: '在“插入代码”中完成并保存草稿' },
    { title: '运行调试', desc: '点击运行查看结果并修正' },
    { title: '插入答案', desc: '将代码回填到富文本中整理说明' },
    { title: '提交任务', desc: '确认无误后提交' }
  ]
  
  // 插入代码弹窗
  const codeDialogVisible = ref(false)
  const codeText = ref('')
  const previewHtml = ref('')
  const runLoading = ref(false)
  const runStatus = ref('idle') // idle | loading | success | error
  const codeLang = ref('javascript')
  const langOptions = [
    { label: 'Python', value: 'python' },
    { label: 'JavaScript', value: 'javascript' },
    { label: 'Java', value: 'java' },
    { label: 'C++', value: 'cpp' },
    { label: 'SQL', value: 'sql' }
  ]
  const monacoEl = ref(null)
  let monacoEditor = null
  
  // 使用纯文本编辑（Element Plus Textarea）
  const toolbar = [
    [{ header: [1, 2, 3, false] }],
    ['bold', 'italic', 'underline', 'strike'],
    [{ color: [] }, { background: [] }],
    [{ list: 'ordered' }, { list: 'bullet' }],
    [{ align: [] }],
    ['link', 'blockquote', 'code-block'],
    ['clean']
  ]
  
  // 高亮通过样式和 ql-syntax 代码块显示，不额外注册 quill 的 syntax 模块以规避 register 报错
  
  const openCodeDialog = () => {
    codeText.value = ''
    previewHtml.value = ''
    runStatus.value = 'idle'
    codeDialogVisible.value = true
    nextTick(() => initMonaco())
  }
  
  const runCodePreview = async () => {
    const code = monacoEditor ? monacoEditor.getValue() : codeText.value
    if (!code || !code.trim()) {
      previewHtml.value = '<div style="padding:12px;color:#999;">无内容</div>'
      return
    }
    const language = (monacoEditor && monacoEditor.getModel && monacoEditor.getModel()) ? (monacoEditor.getModel().getLanguageId() || 'javascript') : 'javascript'
    runLoading.value = true
    runStatus.value = 'loading'
    previewHtml.value = '<div style="padding:12px;color:#666;">⏳ 正在运行，请稍候...</div>'
    try {
      const data = await runAdvanced({
        code,
        language,
        userId: 'student_demo',
        stdin: ''
      })
      if (data && data.success) {
        const out = data.output || '代码执行完成，无输出'
        previewHtml.value = `<pre style=\"padding:12px;white-space:pre-wrap;\">${escapeHtml(out)}</pre>`
        runStatus.value = 'success'
      } else {
        const err = (data && data.error) ? data.error : '执行失败'
        previewHtml.value = `<pre style=\"padding:12px;white-space:pre-wrap;color:#c00;\">${escapeHtml(err)}</pre>`
        runStatus.value = 'error'
      }
    } catch (e) {
      previewHtml.value = `<pre style=\"padding:12px;white-space:pre-wrap;color:#c00;\">网络错误或服务异常：${escapeHtml(e.message || String(e))}</pre>`
      runStatus.value = 'error'
    } finally {
      runLoading.value = false
    }
  }
  
  const escapeHtml = (str) =>
    (str || '')
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/\"/g, '&quot;')
      .replace(/'/g, '&#39;')
  
  const insertCodeIntoEditor = () => {
    // 优先从 Monaco 取值，兜底使用 codeText
    const raw = monacoEditor ? monacoEditor.getValue() : codeText.value
    codeText.value = raw || ''
    // 生成带 ql-syntax 的代码块，便于 highlight.js 与 quill syntax 模块识别
    const html = `<pre class=\"ql-syntax\" spellcheck=\"false\">${escapeHtml(codeText.value)}</pre>`
    // 使用 Quill 的 dangerouslyPasteHTML 在光标处插入
    const editor = quillRef.value?.getQuill?.()
    if (editor) {
      const sel = editor.getSelection(true)
      const index = sel ? sel.index : editor.getLength()
      editor.clipboard.dangerouslyPasteHTML(index, html)
    } else {
      // 退化：直接拼接到末尾
      answer.value = (answer.value || '') + html
    }
    codeDialogVisible.value = false
  }
  
  function initMonaco () {
    if (!monacoEl.value) return
    if (monacoEditor) return
    monacoEditor = monaco.editor.create(monacoEl.value, {
      value: codeText.value || `// JavaScript 示例
  console.log("Hello, World! 我是JavaScript！");
  
  function fibonacci(n) {
      if (n <= 1) return n;
      return fibonacci(n-1) + fibonacci(n-2);
  }
  
  for (let i = 0; i < 10; i++) {
      console.log(\`fibonacci(\${i}) = \${fibonacci(i)}\`);
  }`,
      language: codeLang.value || 'html',
      theme: 'vs-dark',
      automaticLayout: true,
      fontSize: 14,
      minimap: { enabled: false }
    })
    monacoEditor.onDidChangeModelContent(() => {
      codeText.value = monacoEditor.getValue()
    })
  }
  
  function disposeMonaco () {
    if (monacoEditor) {
      monacoEditor.dispose()
      monacoEditor = null
    }
  }
  
  function onChangeLang () {
    if (monacoEditor && monacoEditor.getModel()) {
      monaco.editor.setModelLanguage(monacoEditor.getModel(), codeLang.value)
    }
  }
  
  function goToStep (idx) {
    currentStep.value = idx
    const anchors = ['#task-intro', '#editor-section', '#run-result', '#editor-section', '#editor-section']
    const sel = anchors[idx]
    if (sel) {
      const el = document.querySelector(sel)
      el && el.scrollIntoView({ behavior: 'smooth', block: 'start' })
    }
  }
  
  function nextStep () {
    if (currentStep.value < stepItems.length - 1) {
      goToStep(currentStep.value + 1)
    }
  }
  
  function prevStep () {
    if (currentStep.value > 0) {
      goToStep(currentStep.value - 1)
    }
  }
  
  function goBack () {
    if (window.history.length > 1) {
      router.back()
    } else {
      router.push('/student-tasks')
    }
  }
  
  const loadTask = () => {
    // 优先从 localStorage 读取由任务中心传入的任务
    try {
      const raw = localStorage.getItem(STORAGE_CURRENT)
      if (raw) {
        const parsed = JSON.parse(raw)
        // 如果有路由参数 id，则校验一致性
        const pid = route.params.id ? String(route.params.id) : null
        if (!pid || String(parsed.id) === pid) {
          task.value = parsed
        }
      }
    } catch {}
  }
  
  const loadDraft = () => {
    if (!task.value?.id) return
    const key = ANSWER_KEY_PREFIX + task.value.id
    const raw = localStorage.getItem(key)
    if (raw) answer.value = raw
  }
  
  const saveDraft = async () => {
    if (!task.value?.id) return
    saving.value = true
    try {
      const key = ANSWER_KEY_PREFIX + task.value.id
      localStorage.setItem(key, answer.value || '')
      message.success('草稿已保存')
    } finally {
      saving.value = false
    }
  }
  
  const submitAnswer = async () => {
    if (!task.value?.id) return
    if (!answer.value || answer.value.replace(/<[^>]*>/g, '').trim() === '') {
      return message.warning('请先填写答案后再提交')
    }
    try {
      await new Promise((resolve, reject) => {
        Modal.confirm({
          title: '提交确认',
          content: '确认提交该任务答案？提交后将不可修改。',
          okText: '提交',
          cancelText: '取消',
          onOk: resolve,
          onCancel: reject
        })
      })
    } catch {
      return
    }
    submitting.value = true
    try {
      // 模拟提交
      await new Promise(r => setTimeout(r, 600))
      const key = ANSWER_KEY_PREFIX + task.value.id
      localStorage.setItem(key, answer.value || '')
      message.success('提交成功，返回任务中心')
      router.replace('/student-tasks')
    } finally {
      submitting.value = false
    }
  }
  
  onMounted(() => {
    loadTask()
    loadDraft()
  })
  
  const typeLabel = (t) => ({ coding: '编程', quiz: '测验', project: '项目', reading: '阅读' }[t] || t)
  const difficultyLabel = (d) => ({ easy: '简单', medium: '中等', hard: '困难' }[d] || d)
  const formatDate = (str) => new Date(str).toLocaleDateString('zh-CN')
  </script>
  
  <style scoped>
  .do-task-page { padding: 20px; position: relative; z-index: 1; }
  .fullscreen-bg { position: fixed; inset: 0; background: #ffffff; z-index: -1; }
  
  .page-header { text-align: left; color: #000; margin: 0 0 16px; }
  .back-row { margin: 0 auto 6px; text-align: left; }
  .page-header h1 { margin: 0 0 6px; font-size: 2rem; color: #000; }
  .page-header .subtitle { margin: 0; opacity: 0.95; }
  
  .content-wrap {
    /* max-width: 90%; */
    margin: 0 auto;
    display: grid;
    gap: 20px;
    grid-template-columns: 260px 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas:
      'left intro'
      'left editor';
    align-items: start;
  }
  .steps-panel {
    background: rgba(243, 241, 241, 0.96);
    border-radius: 12px;
    padding: 14px 12px;
    box-shadow: 0 10px 24px rgba(0,0,0,0.08);
    border: 1px solid rgba(0,0,0,0.06);
    position: sticky;
    top: 12px;
    height: fit-content;
  }
  .grid-left { grid-area: left;   height: 99%;}
  .grid-intro { grid-area: intro; }
  .grid-editor { grid-area: editor; }
  .steps-header { font-weight: 400; color: #2c3e50; margin-bottom: 8px; }
  .steps-list { margin: 8px 0; }
  .steps-actions { display: flex; gap: 8px; justify-content: flex-end; }
  
  
  .task-intro { background: rgba(255,255,255,0.98); border-radius: 12px; padding: 18px; box-shadow: 0 10px 24px rgba(0,0,0,0.1); border: 1px solid rgba(0,0,0,0.06); }
  .task-intro h3 { margin: 0 0 8px; color: #2c3e50; }
  .task-intro .desc { color: #5a6c7d; line-height: 1.7; margin: 8px 0 14px; }
  .task-intro .meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 16px; background: #f7f8fa; padding: 12px; border-radius: 10px; border: 1px solid #eef0f3; }
  .task-intro .meta-item { display: flex; color: #5a6c7d; }
  .task-intro .meta-item strong { color: #2c3e50; }
  
  .task-editor { background: rgba(255,255,255,0.98); border-radius: 12px; padding: 0; box-shadow: 0 10px 24px rgba(0,0,0,0.1); border: 1px solid rgba(0,0,0,0.06); }
  .editor-header { display: flex; justify-content: space-between; align-items: center; padding: 14px 16px; border-bottom: 1px solid #eef0f3; }
  .editor-header h3 { margin: 0; color: #2c3e50; letter-spacing: .3px; }
  .editor-header .actions { display: flex; gap: 8px; }
  .editor-card { border: 1px solid #e5e7eb; border-radius: 12px; overflow: hidden; height: 520px; box-shadow: 0 10px 24px rgba(0,0,0,0.06); }
  
  .rich-editor :deep(.ql-container) {
    height: 100%;
  }
  
  .code-editor-wrap { display: flex; grid-template-columns: 1fr 1fr; gap: 12px; }
  
  .monaco-wrap { border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; }
  
  .monaco-container {
    width: 120%;
    height: 360px;
  }
  
  .code-actions {
    margin-top: 8px;
  }
  
  .tip { color: #999; margin-left: 8px; font-size: 12px; }
  
  .code-preview { border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; }
  
  .run-status { padding: 8px 12px; font-size: 13px; border-bottom: 1px solid #eee; background: #f7f8fa; }
  .run-status.success { color: #2e7d32; background: #e8f5e9; }
  .run-status.error { color: #c62828; background: #ffebee; }
  
  .preview-frame {
    width: 100%;
    height: 360px;
    border: 0;
    background: white;
  }
  
  /* editor height handled by textarea autosize */
  
  
  @media (max-width: 768px) {
    .content-wrap { gap: 12px; }
    .task-intro .meta { grid-template-columns: 1fr; }
  }
  </style>
  
  